package com.ivan.hospital.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ivan.hospital.mapper.BookingRuleMapper;
import com.ivan.hospital.mapper.DepartmentMapper;
import com.ivan.hospital.mapper.HospitalMapper;
import com.ivan.hospital.mapper.ScheduleMapper;
import com.ivan.model.entity.hosp.BookingRule;
import com.ivan.model.entity.hosp.Department;
import com.ivan.model.entity.hosp.Hospital;
import com.ivan.model.entity.hosp.Schedule;
import com.ivan.hospital.service.ScheduleService;
import com.ivan.model.vo.hosp.BookingScheduleRuleVo;
import com.ivan.model.vo.hosp.ScheduleQueryVo;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

/*
 * @Author      Ivan
 * @Date        2023/4/4 21:58
 * @Description
 */
@Service
public class ScheduleServiceImpl extends ServiceImpl<ScheduleMapper, Schedule> implements ScheduleService {

    @Autowired
    private ScheduleMapper scheduleMapper;

    @Autowired
    private HospitalMapper hospitalMapper;

    @Autowired
    private DepartmentMapper departmentMapper;

    @Autowired
    private BookingRuleMapper bookingRuleMapper;

    private Calendar cal = Calendar.getInstance();
    /**
     * 添加医院排班
     * @param schedule
     * @return
     */
    @Override
    public int saveSchedule(Schedule schedule) {
        return baseMapper.insert(schedule);
    }

    /**
     * 条件查询医院排班带分页
     * @param current
     * @param limit
     * @param queryVo
     * @return
     */
    @Override
    public Page<Schedule> findByPage(long current, long limit, ScheduleQueryVo queryVo) {
        //分页对象
        Page<Schedule> page = new Page<>(current, limit);
        //查询条件
        QueryWrapper<Schedule> wrapper = new QueryWrapper<>();
        String hoscode = queryVo.getHoscode();//医院编号
        String depcode = queryVo.getDepcode();//科室编号
        String docname = queryVo.getDocname();//医生名称
        if (!StringUtils.isEmpty(hoscode)) {
            wrapper.eq("hoscode", queryVo.getHoscode());
        }
        if (!StringUtils.isEmpty(depcode)) {
            wrapper.like("depcode", queryVo.getDepcode());
        }
        if (!StringUtils.isEmpty(docname)) {
            wrapper.like("docname", queryVo.getDocname());
        }
        return baseMapper.selectPage(page, wrapper);
    }

    /**
     * 根据id查询医院排班
     * @param id
     * @return
     */
    @Override
    public Schedule findById(Long id) {
        return baseMapper.selectById(id);
    }

    @Override
    public int removeById(Long id) {
        return baseMapper.deleteById(id);
    }

    /**
     * 根据idList批量删除医院排班
     * @param idList
     * @return
     */
    @Override
    public int removeByIds(List<Long> idList) {
        return baseMapper.deleteBatchIds(idList);
    }

    /**
     * 修改医院排班
     * @param schedule
     * @return
     */
    @Override
    public int updateSchedule(Schedule schedule) {
        return baseMapper.updateById(schedule);
    }

    /**
     * 根据医院编号和科室编号,查询排班规则数据
     * @param page
     * @param limit
     * @param hoscode
     * @param depcode
     * @return
     */
    @Override
    public Map<String, Object> getBookingScheduleRule(long page, long limit, String hoscode, String depcode) {
        Map<String,Object> result = new HashMap<>();
        //条件查询预约规则
        long start = (page - 1) * limit;
        List<BookingScheduleRuleVo> scheduleRuleVos = scheduleMapper.getScheduleRuleVos(start, limit, hoscode, depcode);
        long total = scheduleMapper.getScheduleRuleVosTotal(start, limit, hoscode, depcode);
        scheduleRuleVos.forEach(vo -> {
            vo.setWorkDateMd(vo.getWorkDate());
            //计算当前预约日期对应星期
            String dayOfWeek = this.getDayOfWeek(vo.getWorkDate());
            vo.setDayOfWeek(dayOfWeek);
        });

        //该方法不能合并docCount
//        QueryWrapper<Schedule> wrapper = new QueryWrapper<>();
//        wrapper.select("work_date as workDate," +
//                        "sum(reserved_number) as reservedNumber," +
//                        "sum(available_number) as availableNumber," +
//                        "count(docname) as docCount")
//                .eq("hoscode", hoscode)
//                .eq("depcode", depcode)
//                .groupBy("work_date", "docname")
//                .orderByAsc("work_date");
//        Page<Schedule> pageObj = new Page<>(page, limit);
//        Page<Schedule> pageRes = baseMapper.selectPage(pageObj, wrapper);
//        List<BookingScheduleRuleVo> bookingScheduleRuleList = new ArrayList<>();
//        List<Schedule> records = pageRes.getRecords();
//        records.forEach(r -> {
//            BookingScheduleRuleVo vo = new BookingScheduleRuleVo();
//            vo.setWorkDate(r.getWorkDate());
//            vo.setWorkDateMd(r.getWorkDate());
//            vo.setReservedNumber(r.getReservedNumber());
//            vo.setAvailableNumber(r.getAvailableNumber());
//            vo.setDocCount(r.getDocCount());//排班医生数量
//
//            //计算当前预约日期对应星期
//            String dayOfWeek = this.getDayOfWeek(r.getWorkDate());
//            vo.setDayOfWeek(dayOfWeek);
//            bookingScheduleRuleList.add(vo);
//        });
        result.put("bookingScheduleRuleList", scheduleRuleVos);
        result.put("total", total);

        //其他基础数据
        Map<String, String> baseMap = new HashMap<>();
        //医院名称
        Hospital hospital = hospitalMapper.selectHospitalNameByCode(hoscode);
        baseMap.put("hosname", hospital.getHosname());
        //科室
        Department department = departmentMapper.getDepartmentByHoscodeAndName(hoscode, depcode);
        //大科室名称
        baseMap.put("bigname", department.getBigname());
        //科室名称
        baseMap.put("depname", department.getDepname());
        //月
        baseMap.put("workDateString", new DateTime().toString("yyyy年MM月"));
        //预约规则
        BookingRule bookingRule = bookingRuleMapper.selectByHoscode(hospital.getHoscode());
        //放号时间
        baseMap.put("releaseTime", bookingRule.getReleaseTime());
        //停号时间
        baseMap.put("stopTime", bookingRule.getStopTime());

        result.put("baseMap", baseMap);
        return result;
    }

    /**
     * 根据日期获取周几数据
     * @param date
     * @return
     */
    public String getDayOfWeek(Date date) {
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;
        return weekDays[w];
    }

    //根据医院编号,科室编号和工作日期,查询排班详细信息
    @Override
    public List<Schedule> getScheduleDetail(String hoscode, String depcode, String workDate) {
        //根据参数查询
        QueryWrapper<Schedule> wrapper = new QueryWrapper();
        wrapper.eq("hoscode", hoscode)
                .eq("depcode", depcode)
                .eq("work_date", workDate);
        List<Schedule> schedules = baseMapper.selectList(wrapper);
        schedules.forEach(s -> this.packageSchedule(s));
        return schedules;
    }

    /**
     * 封装排班详情其他值 医院名称、科室名称、日期对应星期
     * @param schedule
     * @return
     */
    private Schedule packageSchedule(Schedule schedule) {
        //设置医院名称
        schedule.getParam().put("hosname",hospitalMapper.selectHospitalNameByCode(schedule.getHoscode()).getHosname());
        //设置科室名称
        schedule.getParam().put("depname",departmentMapper.getDepartmentByHoscodeAndName(schedule.getHoscode(),schedule.getDepcode()).getDepname());
        //设置日期对应星期
        schedule.getParam().put("dayOfWeek",this.getDayOfWeek(schedule.getWorkDate()));
        return schedule;
    }
}
